package com.protocols.sctp.m3ua.sccp;
import java.rmi.*;

import java.rmi.registry.*;

import java.rmi.server.*;
import java.util.Arrays;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.*;

import com.Main.MyServiceInterface;
import com.Main.ReceiveMessageInterface;
import com.protocols.GeneralProtocolData;
import com.protocols.sctp.SctpHandlerInterface;
import com.protocols.sctp.m3ua.M3uaHandler;
import com.protocols.sctp.m3ua.M3uaHandlerInterface;
import com.protocols.sctp.m3ua.M3uaPayLoadData;
import com.protocols.sctp.m3ua.sccp.tcap.*;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelHandler;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelInitialDP;


 

public class SccpHandler extends java.rmi.server.UnicastRemoteObject implements SccpHandlerInterface,MyServiceInterface{

	// Configuring the Logger
	
	private M3uaHandlerInterface M3uaHandler=null;
	private TcapHandlerInterface TcapHandler=null;    
	private Registry Registry;  
	private Logger Log = Logger.getLogger(this.getClass().getName());
	private Boolean logInfoEnabled=false;
    
    // Default Configuration
    int layerServiceport=9001;
    private String tcaphandlerurl= "TcapHandler";		
    private String m3uahandlerurl= "M3uaHandler";
    private String sccphandlerurl= "SccpHandler";
	int ConnRetry=3000;		
	private String logfile= "var/log/sccp.log";
	private Level loglevel= Level.OFF;
	
    
    public SccpHandler() throws RemoteException {
    	super();
		       
    }
    
    
	
	
	public void initialise() {	
		try{
			Properties properties=null;
			try{			
				properties = new java.util.Properties();
				properties.load( new FileInputStream("General.conf"));
			}catch( IOException e){
				System.out.println("Couldn't locate the Config File");				
				System.exit(0);
			}			
			logfile= properties.getProperty("sccp.log.filepath");
			loglevel= Level.parse(properties.getProperty("sccp.log.level"));
			
			FileHandler filehandler=null;
			try{
				filehandler= new FileHandler(logfile,true);
				filehandler.setFormatter(new SimpleFormatter());
				Log.addHandler(filehandler);
				Log.setLevel(loglevel);				
			}catch( IOException e){
				System.out.println("Issue Opening the Log File. Setting the Log Level to 'OFF'");	
				Log.setLevel(Level.OFF);	
			}
			
			logInfoEnabled=Log.isLoggable(Level.INFO);	
			
			layerServiceport=Integer.valueOf(properties.getProperty("layerservice.port"));
			tcaphandlerurl= properties.getProperty("tcap.layerservice.url");
			m3uahandlerurl= properties.getProperty("m3ua.layerservice.url");
			sccphandlerurl= properties.getProperty("sccp.layerservice.url");
			ConnRetry=Integer.valueOf(properties.getProperty("connectionretryinterval"));		
			
				
			try{
				Registry = LocateRegistry.createRegistry( layerServiceport );
				if(logInfoEnabled)Log.info("Created Registry on Port:"+layerServiceport);
			}catch(RemoteException e){
				Registry = LocateRegistry.getRegistry( layerServiceport );	
				if(logInfoEnabled)Log.info("Obtained Registry from Port:"+layerServiceport);
			}
				
			
			Registry.rebind(sccphandlerurl, this);			
			if(logInfoEnabled)Log.info("Bound Sccp Handler on Url:"+sccphandlerurl);
			
			
		}catch(Exception e){
			
		}
		
	}


	@Override
	public GeneralProtocolData m3uaToSccp(long sessionid, byte input [], int OPC, int DPC) throws RemoteException{
		try{
			if (input[0]==9 && (input[1]&0b00001111)==1 ){	 // SCCP Unit Data
				if(logInfoEnabled)Log.info(sessionid+":Received SCCP Unit Data");
				SccpUnitDataMsg sccpdata = new SccpUnitDataMsg();
				byte [] payload =sccpdata.decode(input);	
				if (sccpdata.CalledParty.getSubSystemNumber()==146||sccpdata.CalledParty.getSubSystemNumber()==147){
					if(logInfoEnabled)Log.info(sessionid+":Handing over to the Tcap Layer");
					TcapHandler.sccpToTcap(sessionid, payload, OPC,DPC, sccpdata.CallingParty.getGlobalTitle(), sccpdata.CalledParty.getGlobalTitle(),sccpdata.CalledParty.getSubSystemNumber() );
				}
			}
		}catch(Exception e){
			Log.warning(sessionid+":Exception Occured :" +e.getClass().getSimpleName()+":"+ Arrays.toString(e.getStackTrace()));

		}
		return null;
	}



	@Override
	public void tcapToSccp(long sessionid,GeneralProtocolData tcapdata,String OGT, String DGT, int OSSN, int DSSN)  throws RemoteException {
	
		try{
			
			if(logInfoEnabled)Log.info(sessionid+": Msg Received from Tcap");
			SccpUnitDataMsg sccpunitdata = new SccpUnitDataMsg();
			sccpunitdata.setSccpClassValue(1);
			sccpunitdata.setMsgHandling(8);
			sccpunitdata.CalledParty.setRoutingIndicator(0);
			sccpunitdata.CalledParty.setGTIndicator(4);
			sccpunitdata.CalledParty.setSubSystemNumber(DSSN);
			sccpunitdata.CalledParty.setGTTranslationType(0);
			sccpunitdata.CalledParty.setGTNumPlan(1);
			sccpunitdata.CalledParty.setGTNatureOfAddress(4);
			sccpunitdata.CalledParty.setGlobalTitle(DGT);
			sccpunitdata.CallingParty.setRoutingIndicator(0);
			sccpunitdata.CallingParty.setGTIndicator(4);
			sccpunitdata.CallingParty.setGTTranslationType(0);
			sccpunitdata.CallingParty.setGTNumPlan(1);
			sccpunitdata.CallingParty.setGTNatureOfAddress(4);
			sccpunitdata.CallingParty.setGlobalTitle(OGT);
			sccpunitdata.CallingParty.setSubSystemNumber(OSSN);
			
			sccpunitdata.Payload=tcapdata;
			if(logInfoEnabled)Log.info(sessionid+":Sending SCCP Stream");
			
			
			M3uaHandler.sccpToM3ua(sessionid, sccpunitdata);
		
		}catch(Exception e){
			Log.warning(sessionid+":Exception Occured :" +e.getClass().getSimpleName()+":"+ Arrays.toString(e.getStackTrace()));
	
		}

		
	}

   
   
	public void establishM3uaConnection() throws Exception
	{
		Boolean retry=true;
		while(retry)
		{
			try{
				M3uaHandler=(M3uaHandlerInterface)(Registry.lookup(m3uahandlerurl));
				retry=false;
				
			}catch(Exception e){	
				Log.severe("Couldn't Obtained the M3uaHandler Instance. Retry in "+ConnRetry+" Secs.");
				Thread.sleep(ConnRetry);
			}
		}
		if(logInfoEnabled)Log.info("Obtained M3uaHandler Instance");
		
		
	}
	
	public void establishTcapConnection() throws Exception
	{
		Boolean retry=true;
		while(retry)
		{
			try{
				TcapHandler=(TcapHandlerInterface)(Registry.lookup(tcaphandlerurl));
				retry=false;
			}catch(Exception e){	
				Log.severe("Couldn't Obtained the TcapHandler. Retry in "+ConnRetry+" Secs.");
				Thread.sleep(ConnRetry);
			}
		}				
		if(logInfoEnabled)Log.info("Obtained TcapHandler Instance");
		
	}
	
	

	@Override
	public void startLayer() throws Exception {
		initialise();
		establishM3uaConnection();
		establishTcapConnection();
		
	}
   
}